﻿#define _CRT_SECURE_NO_WARNINGS	
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <queue>
#include <set>
#include <unordered_map>
using namespace std;
/*
class Buffer
{
private:
	char* data;
public:
	//构造函数（调用深拷贝）
	Buffer(const char* str = "")
	{
		data = new char[strlen(str) + 1];
		strcpy(data, str);
		cout << "构造" << data << endl;
	}
	//拷贝构造（调用深拷贝）
	Buffer(const Buffer& other)
	{
		data = new char[strlen(other.data) + 1];
		strcpy(data, other.data);
		cout << "拷贝构造: " << data << endl;
	}
	//赋值运算符重载
	Buffer& operator=(const Buffer& other)
	{
		if (this == &other) return *this;
		delete[] data;
		data = new char[strlen(other.data) + 1];
		strcpy(data, other.data);
		cout << "赋值: " << data << endl;
		return *this;
	}
	void show() const 
	{
		cout << "当前内容: " << data << endl;
	}
	~Buffer()
	{
		cout << "析构" << data << endl;
		delete[] data;
	}
};
class Buffer {
private:
	char* data;
	int id;
	static int count;

public:
	Buffer(const char* str = "") {
		data = new char[strlen(str) + 1];
		strcpy(data, str);
		id = ++count;
		cout << "[构造] Buffer#" << id << ": " << data << endl;
	}

	Buffer(const Buffer& other) {
		data = new char[strlen(other.data) + 1];
		strcpy(data, other.data);
		id = ++count;
		cout << "[拷贝构造] Buffer#" << id << ": " << data << endl;
	}

	Buffer& operator=(const Buffer& other) {
		if (this == &other) return *this;
		delete[] data;
		data = new char[strlen(other.data) + 1];
		strcpy(data, other.data);
		cout << "[赋值] Buffer#" << id << ": " << data << endl;
		return *this;
	}

	void show() const {
		cout << "[显示] Buffer#" << id << ": " << data << endl;
	}

	~Buffer() {
		cout << "[析构] Buffer#" << id << ": " << data << endl;
		delete[] data;
	}
};

int Buffer::count = 0;
int main()
{
	Buffer a("hello");
	Buffer b = a;
	Buffer c;
	c = a;

	a.show();
	b.show();
	c.show();
	return 0;
}
int main()
{
	vector<pair<string, int>> v = {{ "apple", 3 }, { "banana", 1 }, { "cherry", 2 }};
	sort(v.begin(), v.end(), [](const pair<string, int>& a, const pair<string, int>& b) {
		return a.second < b.second;
		});
	for (auto& p : v)
	{
		cout << p.first << ":" << p.second << endl;
	}
	return 0;
}
class Book {
private:
	int num;
	string title;
public:
	Book(): num(0), title(""){}
	Book(int n, string t)
		:num(n),
		title(t) {}
	void printf() const
	{
		cout << "number: " << num << "," << "title: " << title << endl;
	}
};
class Library {
	string library_name;
	vector<Book> books;
public:
	Library(string name) : library_name(name) {};
	void add(Book b)
	{
		books.push_back(b);
	}
	void printf() const
	{
		cout << "library: " << library_name << endl;
		for (const auto& x : books)
		{
			x.printf();
		}
	}
};

int main()
{
	Book b1(1, "a");
	Book b2(2, "b");
	Book b3(3, "c");
	Book b4(4, "d");
	Library lib("red_library");
	lib.add(b1);
	lib.add(b2);
	lib.add(b3);
	lib.add(b4);
	lib.printf();
	return 0;
}
class Shape
{
public:
	virtual double area() const
	{
		return 0.0;
	}
};
class Rectangle : public Shape {
	double wide;
	double high;
public:
	Rectangle(double w, double h): wide(w), high(h){}
	double area() const override
	{
		return wide * high;
	}
};
class Circle : public Shape {
	double radius;
public:
	Circle(double r) : radius(r){}
	double area() const override
	{
		return 3.14 * radius * radius;
	}
};

int main()
{
	Shape* s1 = new Rectangle(4.23, 5.74);
	Shape* s2 = new Circle(5.5);

	cout << s1->area() << endl;  
	cout << s2->area() << endl;  

	delete s1;
	delete s2;
}
class Base {
public:
	Base(int x) {
		cout << "Base(" << x << ")\n";
	}
};

class Derived : public Base {
	int y;
public:
	using Base::Base; // 继承 Base(int)

	Derived(int x, int y_val) : Base(x), y(y_val) {
		cout << "Derived(" << x << ", " << y_val << ")\n";
	}
};

int main() {
	Derived d1(5);          // 调用 Base(int)，y 未初始化
	Derived d2(1, 10);      // 调用你写的构造函数
}
class Animal {
public:
	virtual void speak()
	{
		cout << "AOWUUU" << endl;
	}
};
class Dog : public Animal {
public:
	void speak() override
	{
		cout << "bark" << endl;
	}
};
void call(Animal* a)
{
	a = new Dog();
	a->speak();
}
int main()
{
	Animal* dd = new Dog();
	dd->speak();
	call(dd);
}
class Room {
	string name;
	static int count;
public:
	Room(const string& n): name(n){
		count++;
	}
	string get_name() const
	{
		return name;
	}
	static int get_count()
	{
		return count;
	}
};
int Room::count = 0;
int main()
{
	Room a("tbx");
	Room b("llt");
	cout << a.get_count() << endl;
}
*/
class Room 
{
	string name;
	string pwd;
	set<int> members;
public:
	Room() = default;
	Room(const string& _name, const string& _pwd = "")
		:name(_name), pwd(_pwd) {}
	void add(int fd)
	{
		members.insert(fd);
	}
	void remove(int fd)
	{
		members.erase(fd);
	}
	bool has(int fd) const
	{
		return members.count(fd) > 0;
	}
	string get_name(int fd) const
	{
		return name;
	}
	bool check_pwd(const string& input) const
	{
		return pwd == input;
	}
	const set<int>& get_members() const
	{
		return members;
	}
};
class RoomManager
{
	unordered_map<string, Room> rooms;
	unordered_map<int, string> fd_to_room;
public:
	RoomManager() {
		rooms["lobby"] = Room("lobby");
	}
	bool join(int fd, const string& name, const string& pwd, string& err)
	{
		if (name == "" || pwd == "")
		{
			err = "Room name/pwd ncannot be empty.\n";
			return false;
		}

		if (!rooms.count(name))
		{
			rooms[name] = Room(name, pwd);
		}
		else
		{
			if (fd_to_room.count(fd) && fd_to_room[fd] == name)
			{
				err = "You are already in " + name + ".\n";
				return false;
			}
			if (!rooms[name].check_pwd(pwd))
			{
				err = "Wrong password.\n";
				return false;
			}
		}
		fd_to_room[fd] = name;
		rooms[name].add(fd);
		return true;
	}
	void leave(int fd)
	{
		if (!fd_to_room.count(fd)) return;
		string old_name = fd_to_room[fd];
		rooms[old_name].remove(fd);
		fd_to_room[fd] = "lobby";
		rooms["lobby"].add(fd);
	}
	string get_user_room(int fd) const
	{
		auto it = fd_to_room.find(fd);
		if(it != fd_to_room.end())
		return it->second;
		return "lobby";
	}
	vector<int> get_members(const std::string& room_name) const
	{
		auto it = rooms.find(room_name);
		if (it == rooms.end()) return {};
		return vector<int>(it->second.get_members().begin(), it->second.get_members().end());
	}
	unordered_map<std::string, std::set<int>> get_all_rooms() const
	{
		std::unordered_map<std::string, std::set<int>> result;
		for (const auto& pair : rooms)
		{
			const std::string& room_name = pair.first;
			const Room& room = pair.second;
			result[room_name] = room.get_members();
		}
		return result;
	}
};
int main()
{
	RoomManager manager;
	string err;
	int fd1 = 10, fd2 = 20, fd3 = 30;
	cout << manager.get_user_room(fd1) << endl;
	
	// 加入新房间（带密码）
	manager.join(fd1, "redroom", "123", err);
	manager.join(fd3, "redroom", "123", err);
	cout << "[redroom members] ";
	for (int fd : manager.get_members("redroom")) cout << fd << " ";
	cout << endl;

	// 加入失败：密码错误
	if (!manager.join(fd2, "redroom", "wrong", err))
		cout << "[Expected fail] " << err;

	// leave 再回 lobby
	manager.leave(fd1);
	cout << "[After leave] fd1 now in: " << manager.get_user_room(fd1) << endl;

	auto all = manager.get_all_rooms();
	cout << "[All rooms] \n";
	for (auto& pair : all) {
		cout << "- " << pair.first << ": ";
		for (int fd : pair.second) cout << fd << " ";
		cout << endl;
	}
	return 0;
}